package com.chenhy.service;

import com.chenhy.mapper.UserMapper;
import com.chenhy.pojo.Role;
import com.chenhy.pojo.User;
import com.chenhy.security.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserMapper userMapper;


    @Autowired
    private RoleService roleService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Transactional
    @Override
    @Cacheable(value = "user", key = "'userList'")
    public List<User> queryAllUser() {
        List<User> users = userMapper.queryAllUser();
        for (User user : users) {
            Role role = roleService.queryRoleById(user.getUserRole());
            user.setUserRoleName(role.getRoleName());
        }
        return users;
    }

    @Override
    public List<User> userFuzzyQuery(String condition) {
        List<User> users = userMapper.userFuzzyQuery(condition);
        for (User user : users) {
            Role role = roleService.queryRoleById(user.getUserRole());
            user.setUserRoleName(role.getRoleName());
        }
        return users;
    }

    @Override
    @CacheEvict(value = "user", key = "'userList'")
    public int addUser(User user) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setCreatedBy(loginUser.getId());
        user.setModifyBy(loginUser.getId());
        return userMapper.addUser(user);
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "user", key = "#id"),
            @CacheEvict(value = "user", key = "'userList'"),
    })
    public int deleteUser(int id) {
        return userMapper.deleteUser(id);
    }

    @Transactional
    @Override
    @Cacheable(value = "user", key = "#id", unless = "#result == null ")
    public User queryUserById(int id) {
        User user = userMapper.queryUserById(id);
        Role role = roleService.queryRoleById(user.getUserRole());
        user.setUserRoleName(role.getRoleName());
        return user;
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "user", key = "#user.id"),
            @CacheEvict(value = "user", key = "'userList'"),
    })
    public int updateUser(User user) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setModifyBy(loginUser.getId());
        return userMapper.updateUser(user);
    }

    @Override
    @CacheEvict(value = "user", key = "#id")
    public int resetPasswordById(int id) {
        return userMapper.resetPasswordById(id);
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "user", key = "#loginUser.id"),
            @CacheEvict(value = "user", key = "'userList'"),
    })
    public Boolean revisePassword(LoginUser loginUser, String oldPassword, String newPassword) {
        if (passwordEncoder.matches(oldPassword, userMapper.queryUserById(loginUser.getId()).getUserPassword())){
            userMapper.revisePassword(loginUser.getId(), passwordEncoder.encode(newPassword));
            return true;
        } else {
            return false;
        }

    }

    @Caching(evict = {
            @CacheEvict(value = "user", allEntries = true),
            @CacheEvict(value = "role", allEntries = true),
            @CacheEvict(value = "customer", allEntries = true),
            @CacheEvict(value = "bill", allEntries = true),
            @CacheEvict(value = "provider", allEntries = true)
    })
    @Override
    public void flushCache(){

    }


}
